/*
 * Copyright (c) 2018 Hitevision
 */

package tw.com.hitevision.whiteboard.android;

import android.graphics.Bitmap;
import android.graphics.PointF;
import android.net.Uri;
import android.view.MotionEvent;

import androidx.annotation.ColorInt;

import java.util.List;

import tw.com.hitevision.whiteboard.android.state.WhiteboardState;
import tw.com.hitevision.whiteboard.android.widgets.ModifiedEditTextForSkia;

public class InputEvent {
    private final int action;

    private final float x;
    private final float y;
    private final float w;
    private final float h;
    private final MotionEvent event;
    private final WhiteboardState state;
    @ColorInt
    private final int color;
    private final Bitmap image;
    private final String text;
    private final int keyCode;
    private final int cursor;
    private Device device;
    private Whiteboard.Input input;
    private Uri uri;
    private String resultUrl;
    private boolean booleanValue;
    private List<PointF> points;

    private InputEvent(int action, float x, float y,float w, float h) {
        this.action = action;
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        this.event = null;
        this.state = null;
        this.color = 0;
        this.image = null;
        this.text = null;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = null;
        this.input = null;
        this.uri = null;
        this.resultUrl = null;
        this.booleanValue = false;
    }

    private InputEvent(MotionEvent event) {
        this.action = Action.TOUCH;
        this.x = 0;
        this.y = 0;
        this.w = 0;
        this.h = 0;
        this.event = event;
        this.state = null;
        this.color = 0;
        this.image = null;
        this.text = null;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = null;
        this.input = null;
        this.uri = null;
        this.resultUrl = null;
        this.booleanValue = false;
    }

    private InputEvent(WhiteboardState state) {
        this.action = Action.SET_WHITEBOARD_STATE;
        this.x = 0;
        this.y = 0;
        this.w = 0;
        this.h = 0;
        this.event = null;
        this.state = state;
        this.color = 0;
        this.image = null;
        this.text = null;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = null;
        this.input = null;
        this.uri = null;
        this.resultUrl = null;
        this.booleanValue = false;
    }

    private InputEvent(int action, @ColorInt int color) {
        this.action = action;
        this.x = 0;
        this.y = 0;
        this.w = 0;
        this.h = 0;
        this.event = null;
        this.state = null;
        this.color = color;
        this.image = null;
        this.text = null;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = null;
        this.input = null;
        this.uri = null;
        this.resultUrl = null;
        this.booleanValue = false;
    }

    private InputEvent(Bitmap image) {
        this.action = Action.ADD_IMAGE;
        this.x = 0;
        this.y = 0;
        this.w = 0;
        this.h = 0;
        this.event = null;
        this.state = null;
        this.color = 0;
        this.image = image;
        this.text = null;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = null;
        this.input = null;
        this.uri = null;
        this.resultUrl = null;
        this.booleanValue = false;
    }

    private InputEvent(int action, Uri uri) {
        this.action = action;
        this.x = 0;
        this.y = 0;
        this.w = 0;
        this.h = 0;
        this.event = null;
        this.state = null;
        this.color = 0;
        this.image = null;
        this.text = null;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = null;
        this.input = null;
        this.uri = uri;
        this.resultUrl = null;
        this.booleanValue = false;
    }

    private InputEvent(int action, String text, float x, float y, float w, float h, int keyCode, int cursor) {
        this.action = action;
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        this.event = null;
        this.state = null;
        this.color = 0;
        this.image = null;
        this.text = text;
        this.cursor = cursor;
        this.keyCode = keyCode;
        this.device = null;
        this.input = null;
        this.uri = null;
        this.resultUrl = null;
        this.booleanValue = false;
    }

    private InputEvent(int action, Device device, Whiteboard.Input input) {
        this.action = action;
        this.x = 0;
        this.y = 0;
        this.w = 0;
        this.h = 0;
        this.event = null;
        this.state = null;
        this.color = 0;
        this.image = null;
        this.text = null;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = device;
        this.input = input;
        this.uri = null;
        this.resultUrl = null;
        this.booleanValue = false;
    }

    private InputEvent(int action, String resultUrl, float x, float y) {
        this.action = action;
        this.x = x;
        this.y = y;
        this.w = 0;
        this.h = 0;
        this.event = null;
        this.state = null;
        this.color = 0;
        this.image = null;
        this.text = null;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = null;
        this.input = null;
        this.resultUrl = resultUrl;
        this.booleanValue = false;
    }

    private InputEvent(int action, String command) {
        this.action = action;
        this.x = 0;
        this.y = 0;
        this.w = 0;
        this.h = 0;
        this.event = null;
        this.state = null;
        this.color = 0;
        this.image = null;
        this.text = command;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = null;
        this.input = null;
        this.resultUrl = null;
        this.booleanValue = false;
    }

    private InputEvent(int action, boolean value) {
        this.action = action;
        this.x = 0;
        this.y = 0;
        this.w = 0;
        this.h = 0;
        this.event = null;
        this.state = null;
        this.color = 0;
        this.image = null;
        this.text = null;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = null;
        this.input = null;
        this.resultUrl = null;
        this.booleanValue = value;
    }

    private InputEvent(int action, List<PointF> points, float degree, int mode) {
        this.action = action;
        this.x = degree;
        this.y = 0;
        this.w = 0;
        this.h = 0;
        this.event = null;
        this.state = null;
        this.color = 0;
        this.image = null;
        this.text = null;
        this.cursor = 0;
        this.keyCode = mode;
        this.device = null;
        this.input = null;
        this.resultUrl = null;
        this.booleanValue = false;
        this.points = points;
    }

    private InputEvent(int action, List<PointF> points) {
        this.action = action;
        this.x = 0;
        this.y = 0;
        this.w = 0;
        this.h = 0;
        this.event = null;
        this.state = null;
        this.color = 0;
        this.image = null;
        this.text = null;
        this.cursor = 0;
        this.keyCode = ModifiedEditTextForSkia.KEYCODE_INVALID;
        this.device = null;
        this.input = null;
        this.resultUrl = null;
        this.booleanValue = false;
        this.points = points;
    }

    static InputEvent createInputChangeAction(Device device, Whiteboard.Input input) {
        return new InputEvent(Action.INPUT_CHANGED, device, input);
    }

    static InputEvent createTouchAction(MotionEvent event) {
        return new InputEvent(event);
    }

    static InputEvent createAction(int action) {
        return new InputEvent(action, 0, 0,0,0);
    }

    static InputEvent createAction(int action, float x, float y) {
        return new InputEvent(action, x, y,0,0);
    }

    static InputEvent createSetStateAction(WhiteboardState state) {
        return new InputEvent(state);
    }

    static InputEvent create(int action, @ColorInt int color) {
        return new InputEvent(action, color);
    }

    static InputEvent createAddImageAction(Bitmap image) {
        return new InputEvent(image);
    }

    static InputEvent createAddImageBySearchingAction(String resultUrl, float x, float y) {
        return new InputEvent(Action.ADD_IMAGE, resultUrl, x, y);
    }

    static InputEvent createAddImageAction(Uri contentUri) {
        return new InputEvent(Action.ADD_IMAGE, contentUri);
    }

    static InputEvent createActiveWordTextChangeAction(String text, float x, float y, float w, float h, int keyCode, int cursor) {
        return new InputEvent(Action.ACTIVE_WORD_TEXT_CHANGED, text, x, y, w, h, keyCode, cursor);
    }

    static InputEvent createGetReadyForSelectionModeAction(String command) {
        return new InputEvent(Action.GET_READY_FOR_SELECTION, command);
    }

    static InputEvent createRemoveActiveItemsAction(boolean clearFrameBuffer) {
        return new InputEvent(Action.REMOVE_ACTIVE_ITEMS, clearFrameBuffer);
    }

    static InputEvent createSetSizeAction(float w, float h) {
        return new InputEvent(Action.SET_SIZE, 0, 0,w,h);
    }

    static InputEvent createProtractorFinish(List<PointF> points, float degree, int mode) {
        return new InputEvent(Action.PROTRACTOR_FINISH, points, degree, mode);
    }

    static InputEvent createProtractorDrawing(List<PointF> points, float degree, int mode) {
        return new InputEvent(Action.PROTRACTOR_DRAWING, points, degree, mode);
    }

    static InputEvent createRulerFinish(List<PointF> points) {
        return new InputEvent(Action.RULER_FINISH, points);
    }

    static InputEvent createRulerDrawing(List<PointF> points) {
        return new InputEvent(Action.RULER_DRAWING, points);
    }

    public int getAction() {
        return action;
    }

    public MotionEvent getEvent() {
        return event;
    }

    @ColorInt
    public int getColor() {
        return color;
    }

    public Bitmap getImage() {
        return image;
    }

    public float getX() {
        return x;
    }

    public float getY() {
        return y;
    }

    public float getW() {
        return w;
    }

    public float getH() {
        return h;
    }

    public int getKeyCode() {
        return keyCode;
    }

    public int getCursor() {
        return cursor;
    }

    public WhiteboardState getState() {
        return state;
    }

    public String getText() {
        return text;
    }

    public Device getDevice() {
        return device;
    }

    public Whiteboard.Input getInput() {
        return input;
    }

    public Uri getUri() {
        return uri;
    }

    public String getResultUrl() {
        return resultUrl;
    }

    public boolean getBooleanValue() {
        return booleanValue;
    }

    public List<PointF> getPoints() {
        return points;
    }

    public static class Action {
        public static final int COPY = 1;
        public static final int CUT = 2;
        public static final int DELETE = 3;
        public static final int MAKE_STICKY_NOTE = 4;
        public static final int PASTE = 5;
        public static final int TOUCH = 6;
        public static final int CLEAR_SELECTION = 7;
        public static final int UNDO = 8;
        public static final int CLEAR_TEXTBOX_CONTROL_KEYBOARD = 9;
        public static final int COLOR_CHANGED = 10;
        public static final int STICKYNOTE_COLOR_CHANGED = 11;
        public static final int SET_WHITEBOARD_STATE = 12;
        public static final int ADD_IMAGE = 13;
        public static final int ACTIVE_WORD_TEXT_CHANGED = 14;
        public static final int UPDATE_STATE_PREVIEW = 15;
        public static final int CLEAR_BOARD = 16;
        public static final int TRIMING = 17;
        public static final int PUSH_END = 18;
        public static final int INPUT_CHANGED = 19;
        public static final int ON_STOP = 20;
        public static final int GET_READY_FOR_SELECTION = 21;
        public static final int INVALIDATE_RENDER = 22;
        public static final int REMOVE_ACTIVE_ITEMS = 23;
        public static final int CLEAN_FRAME_BUFFER = 24;
        public static final int REDO = 25;
        public static final int SET_SIZE = 26;

        public static final int RULER_DRAWING = 32;
        public static final int RULER_FINISH = 33;
        public static final int PROTRACTOR_DRAWING = 34;
        public static final int PROTRACTOR_FINISH = 35;
    }
}
